"""
市场借币杠杆利率和借币限额模块
获取市场借币的利率和限额信息
"""
import time
from typing import Dict, List, Optional
from datetime import datetime, timedelta
from loguru import logger

try:
    import okx.PublicData as PublicData
except ImportError:
    logger.warning("okx SDK未安装，请运行: pip install okx")
    PublicData = None


class InterestRateManager:
    """市场借币杠杆利率和借币限额管理器"""
    
    # 限速配置：2次/2s
    RATE_LIMIT_REQUESTS = 2
    RATE_LIMIT_WINDOW = 2.0  # 秒
    
    def __init__(self, sandbox: bool = True):
        """
        初始化市场借币利率管理器
        
        Args:
            sandbox: 是否使用模拟盘，True=模拟盘(1)，False=实盘(0)
        """
        if PublicData is None:
            raise ImportError("okx SDK未安装，请运行: pip install okx")
        
        self.sandbox = sandbox
        flag = "1" if sandbox else "0"
        
        # 初始化OKX公共数据API
        self.public_api = PublicData.PublicAPI(flag=flag)
        
        # 限速控制
        self.request_times: List[float] = []  # 请求时间戳列表
        
        # 数据缓存
        self.interest_rate_cache: Optional[List[Dict]] = None
        self.cache_expire_time: Optional[datetime] = None
        self.cache_duration = timedelta(hours=1)  # 缓存1小时
        
        logger.info(f"市场借币利率管理器已初始化 (模式: {'模拟盘' if sandbox else '实盘'})")
    
    def _check_rate_limit(self):
        """
        检查并执行限速
        限速规则：2次/2s (IP)
        """
        now = time.time()
        
        # 移除2秒前的请求记录
        self.request_times = [t for t in self.request_times 
                             if now - t < self.RATE_LIMIT_WINDOW]
        
        # 如果达到限速上限，等待
        if len(self.request_times) >= self.RATE_LIMIT_REQUESTS:
            oldest_request = self.request_times[0]
            wait_time = self.RATE_LIMIT_WINDOW - (now - oldest_request)
            
            if wait_time > 0:
                logger.debug(f"触发限速，等待 {wait_time:.2f} 秒")
                time.sleep(wait_time)
                # 重新计算
                now = time.time()
                self.request_times = [t for t in self.request_times 
                                     if now - t < self.RATE_LIMIT_WINDOW]
        
        # 记录本次请求
        self.request_times.append(now)
    
    def get_interest_rate_loan_quota(self, use_cache: bool = True) -> List[Dict]:
        """
        获取市场借币杠杆利率和借币限额
        
        Args:
            use_cache: 是否使用缓存
            
        Returns:
            利率和限额信息列表，每个币种包含以下字段：
            - basic: 基础信息列表
                - ccy: 币种
                - quota: 借币限额
                - rate: 日利率
            - vip: VIP等级信息列表
                - level: VIP等级
                - loanQuota: 借币限额
                - loanQuotaCoef: 借币限额系数
            - regular: 普通用户信息列表
                - level: 等级
                - loanQuota: 借币限额
                - loanQuotaCoef: 借币限额系数
        """
        # 检查缓存
        if use_cache and self.interest_rate_cache is not None:
            if self.cache_expire_time and datetime.now() < self.cache_expire_time:
                logger.debug("从缓存获取市场借币利率和限额信息")
                return self.interest_rate_cache
        
        # 执行限速检查
        self._check_rate_limit()
        
        try:
            logger.info("获取市场借币杠杆利率和借币限额")
            result = self.public_api.get_interest_rate_loan_quota()
            
            # 检查响应
            if result.get("code") != "0":
                error_msg = result.get("msg", "未知错误")
                logger.error(f"获取利率和限额失败: {error_msg}")
                raise RuntimeError(f"API错误: {error_msg}")
            
            # 提取数据
            data_list = result.get("data", [])
            logger.info(f"获取利率和限额成功: {len(data_list)} 条记录")
            
            # 更新缓存
            if use_cache:
                self.interest_rate_cache = data_list
                self.cache_expire_time = datetime.now() + self.cache_duration
            
            return data_list
            
        except Exception as e:
            logger.error(f"获取利率和限额异常: {e}")
            raise
    
    def get_currency_interest_rate(self, ccy: str, use_cache: bool = True) -> Optional[Dict]:
        """
        获取指定币种的利率信息
        
        Args:
            ccy: 币种，如 BTC, ETH
            use_cache: 是否使用缓存
            
        Returns:
            币种利率信息字典，如果不存在返回None
        """
        data_list = self.get_interest_rate_loan_quota(use_cache)
        
        for data in data_list:
            basic_list = data.get("basic", [])
            for basic in basic_list:
                if basic.get("ccy") == ccy:
                    return {
                        "ccy": ccy,
                        "quota": float(basic.get("quota", 0)),
                        "rate": float(basic.get("rate", 0)),
                        "vip": data.get("vip", []),
                        "regular": data.get("regular", [])
                    }
        
        logger.warning(f"未找到币种 {ccy} 的利率信息")
        return None
    
    def get_currency_details(self, ccy: str) -> Dict:
        """
        获取币种详细信息（包含格式化数据）
        
        Args:
            ccy: 币种
            
        Returns:
            详细信息字典：
            - ccy: 币种
            - quota: 借币限额
            - daily_rate: 日利率
            - annual_rate: 年化利率
            - vip_levels: VIP等级信息列表
            - regular_levels: 普通用户等级信息列表
        """
        info = self.get_currency_interest_rate(ccy)
        
        if not info:
            raise ValueError(f"无法获取币种 {ccy} 的利率信息")
        
        # 计算年化利率
        daily_rate = info["rate"]
        annual_rate = daily_rate * 365
        
        # 格式化VIP等级信息
        vip_levels = []
        for vip in info.get("vip", []):
            vip_levels.append({
                "level": vip.get("level"),
                "loan_quota": float(vip.get("loanQuota", 0)),
                "loan_quota_coef": float(vip.get("loanQuotaCoef", 0)),
            })
        
        # 格式化普通用户等级信息
        regular_levels = []
        for regular in info.get("regular", []):
            regular_levels.append({
                "level": regular.get("level"),
                "loan_quota": float(regular.get("loanQuota", 0)),
                "loan_quota_coef": float(regular.get("loanQuotaCoef", 0)),
            })
        
        return {
            "ccy": ccy,
            "quota": info["quota"],
            "daily_rate": daily_rate,
            "annual_rate": annual_rate,
            "annual_rate_pct": annual_rate * 100,
            "vip_levels": vip_levels,
            "regular_levels": regular_levels,
        }
    
    def get_high_rate_currencies(self, min_rate: float = 0.001) -> List[Dict]:
        """
        获取高利率的币种
        
        Args:
            min_rate: 最小日利率，默认0.001 (0.1%)
            
        Returns:
            高利率币种列表
        """
        data_list = self.get_interest_rate_loan_quota()
        
        high_rate_currencies = []
        
        for data in data_list:
            basic_list = data.get("basic", [])
            for basic in basic_list:
                rate = float(basic.get("rate", 0))
                if rate >= min_rate:
                    high_rate_currencies.append({
                        "ccy": basic.get("ccy"),
                        "daily_rate": rate,
                        "annual_rate": rate * 365,
                        "annual_rate_pct": rate * 365 * 100,
                        "quota": float(basic.get("quota", 0)),
                    })
        
        # 按利率排序
        high_rate_currencies.sort(key=lambda x: x["daily_rate"], reverse=True)
        
        return high_rate_currencies
    
    def get_high_quota_currencies(self, min_quota: float = 1000) -> List[Dict]:
        """
        获取高借币限额的币种
        
        Args:
            min_quota: 最小借币限额，默认1000
            
        Returns:
            高限额币种列表
        """
        data_list = self.get_interest_rate_loan_quota()
        
        high_quota_currencies = []
        
        for data in data_list:
            basic_list = data.get("basic", [])
            for basic in basic_list:
                quota = float(basic.get("quota", 0))
                if quota >= min_quota:
                    high_quota_currencies.append({
                        "ccy": basic.get("ccy"),
                        "quota": quota,
                        "daily_rate": float(basic.get("rate", 0)),
                        "annual_rate_pct": float(basic.get("rate", 0)) * 365 * 100,
                    })
        
        # 按限额排序
        high_quota_currencies.sort(key=lambda x: x["quota"], reverse=True)
        
        return high_quota_currencies
    
    def compare_currencies(self, currencies: List[str]) -> List[Dict]:
        """
        比较多个币种的利率和限额
        
        Args:
            currencies: 币种列表
            
        Returns:
            比较结果列表
        """
        results = []
        
        for ccy in currencies:
            try:
                details = self.get_currency_details(ccy)
                results.append({
                    "ccy": ccy,
                    "quota": details["quota"],
                    "daily_rate": details["daily_rate"],
                    "annual_rate_pct": details["annual_rate_pct"],
                })
            except Exception as e:
                logger.error(f"获取 {ccy} 信息失败: {e}")
        
        return results
    
    def get_best_borrow_options(self, max_rate_pct: float = 10.0, 
                                min_quota: float = 100) -> List[Dict]:
        """
        获取最佳借币选项（低利率且高限额）
        
        Args:
            max_rate_pct: 最大年化利率百分比，默认10%
            min_quota: 最小借币限额，默认100
            
        Returns:
            最佳借币选项列表
        """
        data_list = self.get_interest_rate_loan_quota()
        
        best_options = []
        
        for data in data_list:
            basic_list = data.get("basic", [])
            for basic in basic_list:
                quota = float(basic.get("quota", 0))
                rate = float(basic.get("rate", 0))
                annual_rate_pct = rate * 365 * 100
                
                if quota >= min_quota and annual_rate_pct <= max_rate_pct:
                    best_options.append({
                        "ccy": basic.get("ccy"),
                        "quota": quota,
                        "daily_rate": rate,
                        "annual_rate_pct": annual_rate_pct,
                    })
        
        # 按利率排序（从低到高）
        best_options.sort(key=lambda x: x["annual_rate_pct"])
        
        return best_options
    
    def clear_cache(self):
        """清除缓存"""
        self.interest_rate_cache = None
        self.cache_expire_time = None
        logger.info("已清除市场借币利率缓存")
    
    def get_cache_stats(self) -> Dict:
        """
        获取缓存统计信息
        
        Returns:
            缓存统计字典
        """
        is_cached = self.interest_rate_cache is not None
        is_valid = False
        
        if is_cached and self.cache_expire_time:
            is_valid = datetime.now() < self.cache_expire_time
        
        return {
            "is_cached": is_cached,
            "is_valid": is_valid,
            "cache_duration_hours": self.cache_duration.total_seconds() / 3600,
        }


# 便捷函数
def get_interest_rate_loan_quota(sandbox: bool = True) -> List[Dict]:
    """
    便捷函数：获取市场借币杠杆利率和借币限额
    
    Args:
        sandbox: 是否使用模拟盘
        
    Returns:
        利率和限额信息列表
    """
    manager = InterestRateManager(sandbox=sandbox)
    return manager.get_interest_rate_loan_quota()


def get_currency_details(ccy: str, sandbox: bool = True) -> Dict:
    """
    便捷函数：获取币种详细信息
    
    Args:
        ccy: 币种
        sandbox: 是否使用模拟盘
        
    Returns:
        详细信息字典
    """
    manager = InterestRateManager(sandbox=sandbox)
    return manager.get_currency_details(ccy)


def get_best_borrow_options(max_rate_pct: float = 10.0, min_quota: float = 100,
                            sandbox: bool = True) -> List[Dict]:
    """
    便捷函数：获取最佳借币选项
    
    Args:
        max_rate_pct: 最大年化利率百分比
        min_quota: 最小借币限额
        sandbox: 是否使用模拟盘
        
    Returns:
        最佳借币选项列表
    """
    manager = InterestRateManager(sandbox=sandbox)
    return manager.get_best_borrow_options(max_rate_pct, min_quota)
